package com.kgc.scd.service.impl;

/**
 * Created On : 2022/6/13.
 * <p>
 * Author     : nainai
 * <p>
 * Description: 优惠券业务接口实现类
 */

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.kgc.scd.bean.*;
import com.kgc.scd.mapper.CategoryMapper;
import com.kgc.scd.mapper.CouponMapper;
import com.kgc.scd.mapper.CouponUserInnerMapper;
import com.kgc.scd.mapper.UserMapper;
import com.kgc.scd.service.CouponService;
import com.kgc.scd.util.DateUtil;
import com.kgc.scd.util.PageSupport;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class CouponServiceImpl implements CouponService {

    @Autowired(required = false)
    private CouponMapper couponMapper;

    @Autowired(required = false)
    private CouponUserInnerMapper couponUserInnerMapper;

    @Autowired(required = false)
    private CategoryMapper categoryMapper;

    @Autowired(required = false)
    private UserMapper userMapper;

    @Override
    public PageSupport<Coupon> queryCouponByCidAndCidZeroPage(Integer cid, Integer pageNo, Integer pageSize) {
        log.info("查询全品类以及种类id为：{}的优惠券", cid);
        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria criteria = couponExample.createCriteria();

        // cid不为null返回所有优惠券
        if (cid != null) {
            if (cid != 0) {
                criteria.andCouCategoryidIn(Arrays.asList(0, cid)).andCouStatusEqualTo(1);
            } else {
                criteria.andCouCategoryidEqualTo(0).andCouStatusEqualTo(1);
            }
        } else  {
            criteria.andCouStatusEqualTo(1);
        }
        // 分页
        PageHelper.startPage(pageNo, pageSize);
        List<Coupon> coupons = couponMapper.selectByExample(couponExample);
        PageInfo<Coupon> pageInfo = new PageInfo<>(coupons);

        PageSupport<Coupon> pageSupport = new PageSupport<>();
        pageSupport.setPageNo(pageNo);
        pageSupport.setPageSize(pageSize);
        pageSupport.setTotalCount((int) pageInfo.getTotal());
        pageSupport.setTotalPage(pageInfo.getPages());
        pageSupport.setPageData(pageInfo.getList());
        return pageSupport;
    }

    @Override
    public List<CouponUser> queryCouponsByUid(String userId) {
        log.info("查询用户：{},拥有的优惠券", userId);

        // 查询用户拥有的优惠券
        List<CouponUser> coupons = couponUserInnerMapper.selectCouponjoinUserByUid(userId);

        return coupons;
    }

    @Override
    public boolean checkUserCouponPast(String userId) {
        log.info("更新用户：{}已过期优惠券状态", userId);

        // 定义查询条件
        CouponUserInnerExample couponUserInnerExample = new CouponUserInnerExample();
        CouponUserInnerExample.Criteria criteria = couponUserInnerExample.createCriteria();

        // 查询用户已拥有优惠券，并且优惠券状态为未使用
        criteria.andUserIdEqualTo(userId).andInnerStatusEqualTo(0);
        List<CouponUserInner> couponUserInners = couponUserInnerMapper.selectByExample(couponUserInnerExample);
        log.info("用户拥有优惠券：{}", couponUserInners);

        // 用户优惠券过期状态修改
        for (CouponUserInner c : couponUserInners) {
            // 查询当前优惠券有效天数
            log.info("c.getCouid:{}", c.getCouId());
            Integer exprieTime = queryExpireTimeById(c.getCouId());

            // 调用工具类，判断优惠券是否到期
            if (DateUtil.checkCouponPast(c.getReceiveDate(), exprieTime)) {
                // 到期进行修改
                c.setInnerStatus(2);
                couponUserInnerMapper.updateByPrimaryKey(c);
            }
        }
        return true;
    }

    @Override
    public Integer queryExpireTimeById(Integer id) {
        Coupon coupon = couponMapper.selectByPrimaryKey(id);
        log.info("返回对象：{}", coupon);
        return coupon.getCouExpireTime();
    }

    @Override
    public List<Coupon> queryOrderCoupons(String userId, String orderId) {
        log.info("进行订单可用优惠券查询，用户：{}, 订单号：{}", userId, orderId);
        // 根据订单id，查询订单商品信息
        List<OrderItemResult> oir = couponMapper.selectOrderItemResult(orderId);

        log.info("订单：{}，查询到的订单详情：{}", orderId, oir);

        // 可用优惠券结果集合
        List<Coupon> coupons = new ArrayList<>();

        // 对用户已过期的券状态进行更新
        checkUserCouponPast(userId);

        // 返回用户拥有的状态为未使用的优惠券
        List<Coupon> couponList = couponMapper.selectUserCouponByUidAndStatus(userId, 0);
        log.info("用户{}拥有的未使用优惠券：{}", userId, couponList);

        // 查询该订单的总价，判断是否满足通用券条件
        Double totalPrice = 0.0;
        for (OrderItemResult o : oir) {
            totalPrice += o.getProPrice() * o.getItemNum();
        }

        // 根据商品分类计算分类总价
        Map<Integer, Double> cPrice = new HashMap<>();
        for (OrderItemResult o : oir) {
            Double price = o.getProPrice() * o.getItemNum();
            if (cPrice.containsKey(o.getProCategoryid())) {
                // 如果该品类已经存在，在原有基础上增加金额
                cPrice.put(o.getProCategoryid(), cPrice.get(o.getProCategoryid()) + price);
            } else {
                cPrice.put(o.getProCategoryid(), price);
            }
        }
        log.info("根据商品分类计算分类总价:{}", cPrice);

        // 查询可用优惠券
        for (Coupon c : couponList) {
            log.info(c + "--");
            // 为通用券还是品类券
            if (c.getCouCategoryid() == 0) {
                // 为通用券：满足满减条件，或者为折扣券
                if ((c.getCouType() == 0 && totalPrice >= c.getCouFull()) || c.getCouType() == 1) {
                    coupons.add(c);
                }
            } else if (c.getCouCategoryid() != 0){
                // 品类券：为折扣券，或者满足满减条件
                if (c.getCouType() == 1 || (c.getCouType() == 0 && cPrice.get(c.getCouCategoryid()) != null && c.getCouFull() <= cPrice.get(c.getCouCategoryid()))) {
                    coupons.add(c);
                }
            }
        }

        return coupons;
    }

    @Override
    public boolean addCoupons(List<Coupon> couponList) {
        // 添加优惠券

        try {
            for (Coupon c : couponList) {
                List<Coupon> coupons = selectCouponsByName(c.getCouName());
                if (coupons.isEmpty()) {
                    // 优惠券名称不存在，才会执行添加
                    couponMapper.insertSelective(c);
                }
            }
        } catch (Exception e) {
            log.error("添加优惠券异常：{}", e.getMessage());
            return false;
        }

        return true;
    }

    @Override
    public boolean delCoupons(List<Integer> ids) {
        // 删除优惠券
        try {
            ids.forEach(id -> couponMapper.deleteByPrimaryKey(id));
        } catch (Exception e) {
            log.error("删除优惠券异常：{}", e.getMessage());
            return false;
        }

        return true;
    }

    @Override
    public List<Coupon> selectCouponsByName(String couName) {
        CouponExample couponExample = new CouponExample();
        CouponExample.Criteria criteria = couponExample.createCriteria();

        criteria.andCouNameEqualTo(couName);

        return couponMapper.selectByExample(couponExample);
    }

    @Override
    public Coupon selectCouponById(Integer id) {
        return couponMapper.selectByPrimaryKey(id);
    }

    @Override
    public Map<String, String> userGetCoupon(String userId, Integer coId) {
        log.info("用户：{}，领取优惠券：{}", userId, coId);
        Map<String, String> map = new HashMap<>();
        // 查询要领取的优惠券信息
        Coupon coupon = selectCouponById(coId);

        // 判断是否已经拥有此优惠券，并且未使用
        if (couponUserInnerMapper.selectInnerByUidAndStatus0AndCouId(coId, userId) != null){
            map.put("result", "领取失败，已拥有该优惠券未使用！");
            return map;
        }

        // 用户详情
        User user = userMapper.selectByPrimaryKey(userId);
        log.info("用户积分信息为：{}", user);

        if (user.getUserCredit() < coupon.getCouCredit() || coupon.getCouStock() <= 0) {
            log.info("用户积分或优惠券库存不足，用户积分：{}， 库存为：{}", user.getUserCredit(), coupon.getCouStock());
            // 用户积分不足，或者优惠券库存不足
            map.put("result", "领取失败，积分不足，或者优惠券库存不足");
            return map;
        }

        // 满足领取优惠券条件，进行用户积分修改
        User user1 = User.builder()
                .userId(userId)
                .userCredit(user.getUserCredit() - coupon.getCouCredit())
                .build();
        userMapper.updateByPrimaryKeySelective(user1);

        // 更新优惠券用户关联表
        CouponUserInner couponUserInner = CouponUserInner.builder()
                .userId(user.getUserId())
                .couId(coId)
                .innerStatus(0).build();
        couponUserInnerMapper.insertSelective(couponUserInner);

        // 优惠券库存减少
        Coupon coupon1 = Coupon.builder()
                .couId(coId)
                .couStock(coupon.getCouStock() - 1)
                .build();
        couponMapper.updateByPrimaryKeySelective(coupon1);
        map.put("result", "true");
        return map;
    }

    @Override
    public List<OrderItemResult> getOrderItemResult(String orderId) {
        return couponMapper.selectOrderItemResult(orderId);
    }

    @Override
    public boolean changeCouponStatus(List<Integer> coids, Integer status) {
        for (Integer c : coids) {
            Coupon coupon = Coupon.builder()
                    .couId(c)
                    .couStatus(status)
                    .build();
            couponMapper.updateByPrimaryKeySelective(coupon);
        }

        return true;
    }

    @Override
    public boolean changeUserCouponStatus(Integer innerId) {
        CouponUserInner couponUserInner = CouponUserInner
                .builder()
                .innerId(innerId)
                .innerStatus(1)
                .build();

        return couponUserInnerMapper.updateByPrimaryKeySelective(couponUserInner) > 0;
    }

    @Override
    public List<CouponInn> queryCouponInn(String userId, List<Coupon> coupons) {
        // 定义返回结果集
        List<CouponInn> couponInns = new ArrayList<>();

        for (Coupon c : coupons) {
            CouponInn couponInn = couponUserInnerMapper.selectCouponInnByUidAndCouId(userId, c.getCouId());
            if (couponInn.getInnerStatus().equals("0")) {
                couponInn.setInnerStatus("未使用");
            } else if (couponInn.getInnerStatus().equals("1")) {
                couponInn.setInnerStatus("已使用");
            } else if (couponInn.getInnerStatus().equals("2")) {
                couponInn.setInnerStatus("已过期");
            }
            couponInns.add(couponInn);
        }
        return couponInns;
    }


}
